package face.pay.web.com.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import face.pay.common.user.service.UserRegisterBiz;
import face.pay.constant.UserBizType;
import face.pay.constant.UserType;
import face.pay.dao.*;
import face.pay.entity.*;
import face.pay.system.redis.RedisUtils;
import face.pay.util.ResultMessage;
import face.pay.util.bean.JavaBeanUtils;
import face.pay.util.msg.SmsUtil;
import face.pay.util.page.PageData;
import face.pay.util.page.PageParam;
import face.pay.web.com.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    UserInfoDao userInfoDao;

    @Autowired
    UserRegisterBiz userRegisterBiz;

    @Autowired
    private OemConfigInfoDao oemConfigInfoDao;

    @Autowired
    private OemInfoDao oemInfoDao;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    private AgencyLevelDao agencyLevelDao;

    @Autowired
    private AgencyQuotaDao agencyQuotaDao;

    @Autowired
    private ProfitInfoDao profitInfoDao;

    /**
     * 编辑或开下级代理
     * @param roleCode
     * @param userInfo
     * @return
     */
    @Override
    public ResultMessage editUser(UserInfo loginUser,String roleCode, UserInfo userInfo) {
        log.info("用户编辑:"+userInfo.toString());

        Integer  userId = loginUser.getId();

        Integer oemId = loginUser.getOemId();
        userInfo.setUserName(userInfo.getUserName().trim());
        userInfo.setMobile(userInfo.getMobile().trim());
        userInfo.setRecommendId(userId);

        userInfo.setOemId(oemId);

        if(userInfo.getId()==null){
            /**
             * 验证用户名称
             */
            Integer count =  this.userInfoDao.countByOemAndUserName(oemId,userInfo.getUserName());
            if(count<=0) {

                /**
                 * 验证手机号码
                 */
                Integer phone_count =  this.userInfoDao.countByOemIdAndTypeAndPhone(oemId,userInfo.getType(),userInfo.getMobile().trim(),null);

                if(phone_count<=0){

                    userInfo.setCreatedBy(userId);

                    String type = loginUser.getType();

                    /**
                     * 当前注册用户类型为 AGENCY 验证代理级别
                     * 以及新建默认商检分润
                     */
                    if(UserType.AGENCY.equals(userInfo.getType())){

                        Integer levelId = userInfo.getLevelId();
                        if(levelId==null){
                            return ResultMessage.createFail("未指定代理商级别,请完善等级设置，在重新刷新页面");
                        }
                    }else if(UserType.ENTERPRISE.equals(userInfo.getType())){
                        Integer profitId = userInfo.getProfitId();
                        if(profitId==null){
                            return ResultMessage.createFail("未指定商家分润信息,请添加分润设置，在重新刷新页面");
                        }

                    }

                    /**
                     * 代理开代理 则需要验证配额情况
                     */
                    if(UserType.AGENCY.equals(type) && UserType.AGENCY.equals(userInfo.getType())){

                        Integer levelId = userInfo.getLevelId();
                        AgencyQuota agencyQuota =  agencyQuotaDao.getQuotaByUserIdAndLevelId(loginUser.getId(),levelId);
                        if(agencyQuota!=null){
                            Integer quantity = agencyQuota.getQuantity();
                            /**
                             * 当前等级名额 大于1
                             */
                            if(quantity>=1){
                                /**
                                 * 验证当前代理级别 配额
                                 */
                                Boolean isSuccess =  this.userRegisterBiz.registUserWithRole(roleCode, userInfo);

                                if(isSuccess){
                                    /**
                                     * 扣除名额 减1
                                     */
                                    agencyQuota.setQuantity(-1);
                                    this.agencyQuotaDao.addquantity(agencyQuota);
                                }

                            }else {

                                return ResultMessage.createError("该等级名额不足");

                            }
                        }else {
                            return ResultMessage.createError("该等级名额不足");

                        }
                    }else {

                        /**
                         *
                         *
                         */

                        this.userRegisterBiz.registUserWithRole(roleCode, userInfo);

                    }


                    /**
                     * 代理商开完之后则需要 分配默认商家分润
                     */
                    if(UserType.AGENCY.equals(userInfo.getType())){

                        Integer agencyId = userInfo.getId();
                        ProfitInfo profitInfo =  new ProfitInfo();
                        profitInfo.setName("默认分润");
                        profitInfo.setConsumeProfit(new Double(0));
                        profitInfo.setRecConsumeProfit(new Double(0));
                        profitInfo.setCreatedBy(loginUser.getId());
                        profitInfo.setAgencyId(agencyId);
                        this.profitInfoDao.insert(profitInfo);

                    }

                }else {
                    return ResultMessage.createError("手机号码已被注册");
                }

            }else {

                return ResultMessage.createError("用户名已经存在");

            }
        }else {
            userInfo.setUpdatedBy(userId);

            this.userRegisterBiz.updateUser(userInfo);
        }

        return ResultMessage.createSuccess();
    }

    @Override
    public PageData queryPage( UserInfo loginUser,  UserInfo userInfo, PageParam pageParam) {


        userInfo.setOemId(loginUser.getOemId());

        /**
         * OEM 商户查看所有商户
         */
        if(!UserType.OEM.equals(loginUser.getType())){
            userInfo.setRecommendId(loginUser.getId());
        }


        PageHelper.startPage(pageParam.getPageNo(),pageParam.getPageSize());


        List<UserInfo> userInfoList = this.userRegisterBiz.queryList(userInfo);

        List<UserInfo> list = userInfoList.stream().map(user -> {
            String s = user.getCreatedTime().substring(0, 19);
            user.setCreatedTime(s);
            return user;
        }).collect(Collectors.toList());

        PageInfo<UserInfo> pageInfo = new PageInfo <UserInfo>(userInfoList);

        PageData<UserInfo> pageData = new PageData<UserInfo>(pageInfo.getTotal(),list);

        return pageData;
    }

    /**
     * 查询用户详细资料
     * @param loginUser
     * @return
     */
    @Override
    public UserInfo queryUserInfo(UserInfo loginUser) {
        UserInfo userdata= userInfoDao.getById(loginUser.getId());
        String mobile = userdata.getMobile();
        if(StringUtils.isNotBlank(mobile)){
            mobile =  mobile.substring(0,3)+"****"+mobile.substring(7,11);
            userdata.setMobile(mobile);
        }
        userdata.setPassWord(null);
        return userdata;
    }


    /**
     * 发送验证码
     * @param user
     * @param bizType
     * @return
     */
    @Override
    public ResultMessage sendValidateCode(UserInfo user, String bizType) {
        try{
            Integer oemId = user.getOemId();

            OemConfigInfo oemConfigInfo =  this.oemConfigInfoDao.getByOemId(oemId);

            String templateCode = null;

            String keyCode = "code";

            if(UserBizType.PASS_WORD_MODIFY.equals(bizType)) {
                templateCode= oemConfigInfo.getPassModifyCode();
            }else if(UserBizType.PASS_WORD_REST.equals(bizType)) {
                templateCode= oemConfigInfo.getPassResetCode();
                keyCode = "password";
            }else if(UserBizType.USER_INFO_MODIFY.equals(bizType)) {
                templateCode= oemConfigInfo.getUserValidateCode();
            }

            String key = bizType+":"+user.getId();

            String validateCode = JavaBeanUtils.generatesNumNonceStr(6);

            Map<String,String> map = new HashMap<>();

            map.put(keyCode,validateCode);

            String json = JSON.toJSONString(map);

            redisUtils.set(key,validateCode,300);

            SendSmsResponse sendSmsResponse =  SmsUtil.sendSms(user.getMobile(),oemConfigInfo.getSignName(),templateCode,json,oemConfigInfo.getAccessKeyId(),oemConfigInfo.getAccessKeySecret());

            String code =    sendSmsResponse.getCode();
            String message =    sendSmsResponse.getMessage();

            if("OK".equals(code)&&"OK".equals(code)) {
                return ResultMessage.createSuccess("验证码已经发送");
            }else {
                log.error("发送验证码失败:"+message);

            }
        }catch (Exception e){

            log.error("获取验证码失败",e);
        }



        return  ResultMessage.createFail("验证码发送失败");
    }


    /**
     * 更改用户信息
     * @param userInfo 用户信息
     * @param code 验证码
     * @param id 用户id
     * @return
     */
    @Override
    public ResultMessage updateUserInfo(UserInfo userInfo, String code, Integer id) {
        String message = "更新失败";
        String codeKey=UserBizType.USER_INFO_MODIFY+":"+id;
        String redisCode = (String)redisUtils.get(codeKey);
        if(redisCode!=null &&  redisCode.equals(code)){

            userInfo.setId(id);
            userInfoDao.updateUserInfo(userInfo);
            redisUtils.delete(codeKey);
            log.info("用户资料修改成功id:"+id);
            return ResultMessage.createSuccess();
        }else {
            //验证码不存在或者验证码不正确
            message = "验证码错误";
        }
        return  ResultMessage.createFail(message);
    }

    @Override
    @Transactional
    public ResultMessage modifyPassword(UserInfo loginUser, String validateCode, String newPassword) {

        /**
         * 验证用户验证码
         */
        String codeKey= UserBizType.PASS_WORD_MODIFY+":"+loginUser.getId();
        String redisValidateCode = (String)redisUtils.get(codeKey);

        if(validateCode.equals(redisValidateCode)){
            redisUtils.delete(codeKey);
            loginUser.setDeleted(0);
            return  userRegisterBiz.modifyPassword(loginUser,newPassword);

        }else {

            return  ResultMessage.createFail("验证码错误");
        }

    }

    @Override
    public ResultMessage restPassword(String domain, String userName, String phone) {
        //根据domain查出oem商
        OemInfo record = new OemInfo();

        String userType= UserType.AGENCY;

        if(domain.startsWith("agency.")){
            userType= UserType.AGENCY;
            record.setAgencyDomain(domain);
        }else{
            userType=UserType.ENTERPRISE;
            record.setEnterpriseDomain(domain);

        }

        OemInfo oemInfo = oemInfoDao.getOemInfo(record);



        if(oemInfo!=null){
            //根据oemid和用户名看用户是否输入了正确的资料
            UserInfo userInfo = new UserInfo();
            userInfo.setOemId(oemInfo.getId());
            userInfo.setUserName(userName);
            userInfo.setMobile(phone);
            userInfo.setType(userType);
            userInfo.setDeleted(0);
            UserInfo userData = userInfoDao.queryUser(userInfo);
            if(userData!=null){//用户输入的找回密码数据正确
                //生成新密码
                String newPassword = JavaBeanUtils.generatesNumNonceStr(6);
                //找oemConfig
                OemConfigInfo oemConfigInfo =  this.oemConfigInfoDao.getByOemId(userData.getOemId());
                String templateCode= oemConfigInfo.getPassResetCode();
                //开始发送新密码给用户
                Map<String,String> map = new HashMap<>();

                map.put("password",newPassword);

                String json = JSON.toJSONString(map);

                SendSmsResponse sendSmsResponse = null;
                try {
                    sendSmsResponse = SmsUtil.sendSms(userData.getMobile(),oemConfigInfo.getSignName(),templateCode,json,oemConfigInfo.getAccessKeyId(),oemConfigInfo.getAccessKeySecret());
                } catch (ClientException e) {
                    log.error("发送验证码失败:"+e);
                    return ResultMessage.createFail("验证码发送失败");
                }
                String code =    sendSmsResponse.getCode();
                String message =    sendSmsResponse.getMessage();
                if("OK".equals(code)&&"OK".equals(message)) {
                    //更改密码保存到数据库
                    userData.setPassWord(new BCryptPasswordEncoder().encode(newPassword));
                    this.userInfoDao.updatePassword(userData);
                    return ResultMessage.createSuccess("重置密码已经发送");
                }else {
                    log.error("发送验证码失败:"+message);
                    return ResultMessage.createFail("发送验证码失败");
                }

            }else {
                //用户输入的找回密码数据不正确
                return ResultMessage.createFail("您输入的资料不正确");
            }

        }else {
            return ResultMessage.createFail("域名未注册");

        }
    }

    @Override
    public ResultMessage updateMobile(UserInfo userInfo, String code, UserInfo loginUser) {
        return null;
    }
}
